package br.com.mauricioreis.db;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class GenericDAO extends SQLiteOpenHelper {

    private static final String TAG = "GenericDAO";
    private static SQLiteDatabase db;
    private static String nomeBanco;
    private static String nomeTabela;
    private static String sql;
    public static final String KEY_ID = "id";

    private static GenericDAO instance;

    private GenericDAO(Context contexto, String nomeBanco, String sql, String nomeTabela, int ver) {
        super(contexto, nomeBanco, null, ver);
        Log.i(TAG, "Creating or opening database [ " + nomeBanco + " ].");
        // TODO rever forma de criação do banco
        GenericDAO.sql = sql;
        GenericDAO.nomeBanco = nomeBanco;
        GenericDAO.nomeTabela = nomeTabela;
    }

    public static GenericDAO getInstance(Context ctx, String dbName, String sql, String tableName, int ver) {
        if (instance == null) {

            instance = new GenericDAO(ctx, dbName, sql, tableName, ver);
            try {
                Log.i(TAG, "Creating or opening the database [ " + dbName + " ].");
                db = instance.getWritableDatabase();
            } catch (SQLiteException se) {
                Log.e(TAG, "Cound not create and/or open the database [ " + dbName + " ] that will be used for reading and writing.", se);
            } catch (Exception e) {
                Log.e(TAG, "algum erro generico aconteceu", e);
            }
        }
        return instance;
    }

    @Override
    public void close() {
        if (instance != null) {
            Log.i(TAG, "Closing the database [ " + nomeBanco + " ].");
            db.close();
            instance = null;
        }
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        Log.i(TAG, "Trying to create database table if it isn't existed [ " + sql + " ].");
        try {
            // Cria todas as tabelas
            for (String sqlCriacao : Entidade.SQL_DATABASE_CREATE) {
                db.execSQL(sqlCriacao);
            }
            // importa dados da tabela TACO
            for (String sqlCriacao : Entidade.SQL_TABELA_TACO) {
                db.execSQL(sqlCriacao);
            }

        } catch (SQLException se) {
            Log.e(TAG, "Cound not create the database table according to the SQL statement [ " + sql + " ].", se);
        }
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Log.i(TAG, "Upgrading database from version " + oldVersion + " to " + newVersion + ", which will destroy all old data");
        try {
            db.execSQL("DROP TABLE IF EXISTS " + nomeTabela);
        } catch (SQLException se) {
            Log.e(TAG, "Cound not drop the database table [ " + nomeTabela + " ].", se);
        }
        onCreate(db);
    }

    // TODO mudar para insert (Entidade entidade)
    public long inserir(String table, ContentValues values) {
        return db.insert(table, null, values);
    }

    public Cursor get(String table, String[] columns) {
        return db.query(table, columns, null, null, null, null, null);
    }

    public Cursor get(String tabela, String[] colunas, long id) {
        Cursor cursor = db.query(true, tabela, colunas, KEY_ID + "=" + id, null, null, null, null, null);
        if (cursor != null) {
            cursor.moveToFirst();
        }
        return cursor;
    }

    public Cursor getComWhere(String tabela, String[] colunas, String where) {
        Cursor cursor = db.query(true, tabela, colunas, where, null, null, null, null, null);
        if (cursor != null) {
            cursor.moveToFirst();
        }
        return cursor;
    }

    /**
     * Executa um sql no banco e retorna o cursor desta consulta
     * 
     * @param sql
     * @param argumentosDeSelecao
     * @return
     */
    public Cursor getComQuery(String sql, String[] argumentosDeSelecao) {
        Cursor cursor = db.rawQuery(sql, argumentosDeSelecao);
        if (cursor != null) {
            cursor.moveToFirst();
        }
        return cursor;
    }

    public int deletar(String table) {
        return db.delete(table, "1", null);
    }

    public int deletar(String table, long id) {
        return db.delete(table, KEY_ID + "=" + id, null);
    }

    public int deletar(String table, String where) {
        return db.delete(table, where, null);
    }

    // TODO mudar para atualizar (Etidade enidade)
    public int atualizar(String table, long id, ContentValues values) {
        return db.update(table, values, KEY_ID + "=" + id, null);
    }

}